kotlin+mvvm+databinding+recyclerview
上一篇講了activity跟xml,今天來看看adapter與viewmodel
class Adapter<T>(
@LayoutRes val resource: Int,
val listener: Any? = null
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val data: List<T>
get() = _data.toList()
private val _data: MutableList<T> = mutableListOf()
//這個function有更好的寫法,因為我現在這樣寫若是recyclerview有移動還是會被刷新
fun updateData(list: ArrayList<T>){
_data.clear()
_data.addAll(list)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = DataBindingUtil.inflate<ViewDataBinding>(layoutInflater, resource, parent,false)
return MyViewHolder(binding)
}
override fun getItemCount(): Int {
return data.size
}
//這邊的<*>簡單來說就是表任何型態
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is Adapter<*>.MyViewHolder){
val item = data[position]
if (item != null)
holder.setupData(item)
}
}
//這邊是包在裡面的class記得要用inner否則會被預設為外面
inner class MyViewHolder( var binding: ViewDataBinding):RecyclerView.ViewHolder(binding.root){
fun setupData(post: Any){
binding.setVariable(BR.Post, post)
binding.setVariable(BR.listener, listener)
}
}
}
再來是viewmodel
class ViewModel(application: Application): AndroidViewModel(application) , Listener<Post>{
override fun onClick(post: Post){
Toast.makeText(getApplication(), post.post, Toast.LENGTH_SHORT).show()
}
val data = MutableLiveData<ArrayList<Post>>()
val listener:Listener<Post>? = this
fun fetchData(){
val tempArr = ArrayList<Post>()
tempArr.add(Post(post = "1"))
tempArr.add(Post(post = "2"))
tempArr.add(Post(post = "3"))
data.value = tempArr
}
}
這邊我簡單的做了一筆假資料然後因為我需要getApplication所以要使用AndroidViewModel,他是繼承於viewmodel而且可以傳application若只使用viewmodel,就無法使用application``